#include "../inc/game.h"

/*
开发板大小：800*480
触摸屏大小：800*480
触摸屏坐标范围：x:0-800 y:0-480
*/


/****************贪吃蛇游戏代码开始****************/

/**
 * @brief 贪吃蛇游戏主循环函数
 *
 * 负责处理贪吃蛇游戏的主要逻辑流程，包括：
 * 1. 初始化游戏对象
 * 2. 运行游戏主循环
 * 3. 处理游戏结束逻辑（重新开始或退出）
 * 4. 检测退出按钮事件
 *
 * 函数通过触摸事件坐标判断用户操作：
 * - (60,270)-(170,320)区域：重新开始游戏
 * - (300,270)-(410,320)区域：返回游戏选择界面
 * - (700,0)-(800,60)区域：退出按钮（返回游戏选择界面）
 *
 * @note 游戏循环会持续运行直到用户选择退出
 */
void Game::snakePlay(std::string username, bool userLoginFlag)
{
    // 创建贪吃蛇对象，棋盘大小32x32，起始位置(15,15)
    SnakeGame game(32, 32, 15, 15); 

    //声明ReturnInterfaceFlag类
    ReturnInterfaceFlag Sflag;

    Sflag.userLoginFlag = userLoginFlag;     //保存用户登录标志
    Sflag.UserName=username;                 //保存用户名
    cout<<"用户名："<<Sflag.UserName<<endl;  //打印用户名

    // 创建滑动检测器实例，获取触摸事件坐标
    SwipeDetector detector;

    while (1) 
    {
        if (game.play())// 开始游戏
        {
            return; //返回游戏选择界面
        }

        detector.resetTouchState();//清除触摸事件坐标
        detector.detectSwipe();// 检测滑动事件,获取触摸事件坐标
        // 判断是否按了EXIT按钮，如果是就退出，回到游戏选择界面
        if (detector.getX() >= 700 && detector.getX() <= 800 && detector.getY() >= 0 && detector.getY() <= 60)
        {
            return; //返回游戏选择界面
        }
        // 判断是否按倒从新开始
        else if (detector.getX()>=60 && detector.getX()<=170&& detector.getY()>=270&& detector.getY()<=320) 
        {
            game.restart();
        }
        // 判断是否按到退出游戏选择界面
        else if(detector.getX()>=300 && detector.getX()<=410&&detector.getY()>=270&&detector.getY()<=320)
        {
            return; //返回游戏选择界面
        }
    }
}

/****************贪吃蛇游戏代码结束****************/

/****************2048游戏代码开始****************/

/**
 * @brief 2048游戏主函数
 *
 * 该函数启动一个2048游戏实例，初始化游戏板，并根据用户输入控制游戏进程。
 *
 * @param username 用户名（可选），默认为空字符串
 * @param userLoginFlag 用户登录标志（可选），默认为false
 */
void Game::_2048Play(std::string username, bool userLoginFlag)//2048游戏主函数
{
    bool condition = false; // 用于标记游戏是否胜利
    bool musicPlayFlag = true; // 音乐播放标志位，默认为false
    char _2text[50];

    BMP _2048Face("./2048/2048Face.bmp");//加载2048游戏界面图片
    BMP _2048GameOver("./2048/2048GameOver.bmp");
    BMP _2048Win("./2048/2048Win.bmp");

    Game2048 game;//创建2048游戏实例
    SwipeDetector detector;//创建滑动检测器，获取坐标信息
    SwipeDetector::Direction direction;//滑动方向枚举类型变量，用于存储用户滑动的方向

    MusicPlayer player;//创建音乐播放器实例，用于播放背景音乐和得分音效

    
    ReturnInterfaceFlag _2flag;//声明ReturnInterfaceFlag类
    ShowFont* _2showFont = ShowFont::instance();//创建ShowFont对象,打印文字

    _2flag.userLoginFlag = userLoginFlag;     //保存用户登录标志
    _2flag.UserName=username;                 //保存用户名
    cout<<"用户名："<<_2flag.UserName<<endl;  //打印用户名

    game.initialize();//初始化游戏板
    _2048Face.show(Lcd::instance()->addr(), 0, 0);// 显示2048游戏界面图片
    game.printBoard();//打印游戏板

    // 判断是否是用户登录
    if (_2flag.userLoginFlag == true)
    {
        // 显示历史最高分
        sprintf(_2text, "%d", UserManager::getInstance().getUserHighScore(_2flag.UserName ,"2048"));//flag.UserName为用户名，Snake为游戏名称
        _2showFont->display(_2text, 32, 100, 32, ShowFont::purple, ShowFont::white, 630, 154);
        // 显示用户名
        sprintf(_2text, "%s", _2flag.UserName.c_str());//flag.UserName为用户名
        _2showFont->display(_2text, 32, 100, 32, ShowFont::purple, ShowFont::white, 590, 15);
    }

    
    player.play("./2048/2048.mp3");//播放背景音乐

    TimeDisplay _2048_timeDisplay;//创建时间类实例，用于显示时间
    _2048_timeDisplay.start();//打印时间

    while (game.canMove() && !game.isWin())//游戏没结束时循环执行以下操作
    {
        direction = detector.detectSwipe();
        
        if (player.isFinished()) 
        {
        std::cout << "音乐播放结束，重新播放" << std::endl;
        player.play("./2048/2048.mp3");
        }

        switch (direction) 
        {
            case SwipeDetector::UP:
                std::cout << "向上滑动" << std::endl;
                game.move(Game2048::Direction::UP);
                game.printBoard();//打印游戏板
                break;
            case SwipeDetector::DOWN:
                std::cout << "向下滑动" << std::endl;
                game.move(Game2048::Direction::DOWN);
                game.printBoard();//打印游戏板
                break;
            case SwipeDetector::LEFT:
                std::cout << "向左滑动" << std::endl;
                game.move(Game2048::Direction::LEFT);
                game.printBoard();//打印游戏板
                break;
            case SwipeDetector::RIGHT:
                std::cout << "向右滑动" << std::endl;
                game.move(Game2048::Direction::RIGHT);
                game.printBoard();//打印游戏板
                break;
            case SwipeDetector::NONE:
                std::cout << "无有效滑动" << std::endl;// 无有效滑动
                cout<<"X:"<<detector.getX()<<"y:"<<detector.getY()<<endl;
                
                // 判断是否点击了返回按钮
                if (detector.getX() >= 700 && detector.getX() <= 800 && 
                    detector.getY() >= 0   && detector.getY() <= 60)
                {
                    _2048_timeDisplay.stop();//停止时间显示
                    player.stop();//结束音乐播放
                    return;//返回游戏选择界面
                }
                // 判断是否点击了重新开始按钮
                else if (detector.getX() >= 590 && detector.getX() <= 705 && 
                         detector.getY() >= 280 && detector.getY() <= 335)
                {
                    detector.setXY(0, 0);
                    game.initialize();//重新开始游戏
                    //如果是用户登入，判断是否是他的最高分:如果是，把最终分数存入文件
                    if (_2flag.userLoginFlag == true)
                    {
                        // 判断本局是否是历史最高分:如果是，把最终分数存入文件
                        if (game.getScore() > UserManager::getInstance().getUserHighScore(_2flag.UserName,"2048")) // 打开文件用于写入
                        {
                            UserManager::getInstance().updateUserScore(_2flag.UserName,"2048",game.getScore()); // 更新分数
                        }
                    }
                    //分数重置为0
                    game.setScore(0);
                    game.initialize();//初始化游戏板
                    game.printBoard();//打印游戏板
                    condition=false;//运行判断语句的标志位设置为false，跳出循环
                    
                    break;//重启游戏
                }
                // 判断是否点击了音乐暂停按钮
                else if (detector.getX() >= 715 && detector.getX() <= 800 && 
                         detector.getY() >= 220 && detector.getY() <= 310)
                {
                    if (musicPlayFlag == true)
                    {
                        // 暂停
                        player.pause();
                        std::cout << "Paused playback" << std::endl;
                        musicPlayFlag = false;
                    }
                    else
                    {
                        // 继续播放
                        player.resume();
                        std::cout << "Resumed playback" << std::endl;
                        musicPlayFlag = true;
                    }
                }
                break;
        }

        //打印分数
        sprintf(_2text, "%d", game.getScore());
        _2showFont->display(_2text, 32, 100, 32, ShowFont::purple, ShowFont::white, 630, 224);

        
    
        if (game.isWin()) // 如果赢了
        {
            // 如果是用户登录，判断是否是他的最高分
            if (_2flag.userLoginFlag) 
            {
                if (game.getScore() > UserManager::getInstance().getUserHighScore(_2flag.UserName, "2048")) 
                {
                    UserManager::getInstance().updateUserScore(_2flag.UserName, "2048", game.getScore());
                }
            }
            player.stop();//结束音乐播放
            //打印游戏胜利
            _2048Win.show(Lcd::instance()->addr(), 0, 0);
            std::cout << "Congratulations! You won!\n";
            condition = true;
        } 
        else if (!game.canMove())// 如果输了
        {
            // 如果是用户登录，判断是否是他的最高分
            if (_2flag.userLoginFlag) 
            {
                if (game.getScore() > UserManager::getInstance().getUserHighScore(_2flag.UserName, "2048")) {
                    UserManager::getInstance().updateUserScore(_2flag.UserName, "2048", game.getScore());
                }
            }
            player.stop();//结束音乐播放
            _2048GameOver.show(Lcd::instance()->addr(), 0, 0);// 打印游戏结束图片
            std::cout << "Game Over!\n";
            condition = true;
        }

        while (condition)//等待用户点击重新开始按钮或返回按钮
        {
            detector.detectSwipe();
            // 判断是否点击了返回按钮
            if (detector.getX() >= 700 && detector.getX() <= 800 && 
                detector.getY() >= 0   && detector.getY() <= 60)
            {
                _2048_timeDisplay.stop();//停止时间显示
                player.stop();//结束音乐播放
                return;//返回游戏选择界面
            }
            // 判断是否点击了重新开始按钮
            else if (detector.getX() >= 590 && detector.getX() <= 705 && 
                    detector.getY() >= 280 && detector.getY() <= 335)
            {
                detector.setXY(0, 0);
                game.initialize();//重新开始游戏
                //如果是用户登入，判断是否是他的最高分:如果是，把最终分数存入文件
                if (_2flag.userLoginFlag == true)
                {
                    // 判断本局是否是历史最高分:如果是，把最终分数存入文件
                    if (game.getScore() > UserManager::getInstance().getUserHighScore(_2flag.UserName,"2048")) // 打开文件用于写入
                    {
                        UserManager::getInstance().updateUserScore(_2flag.UserName,"2048",game.getScore()); // 更新分数
                    }
                }
                //分数重置为0
                game.setScore(0);
                game.initialize();//初始化游戏板
                game.printBoard();//打印游戏板
                condition=false;//运行判断语句的标志位设置为false，跳出循环
                
                break;//重启游戏
            }
            // 判断是否点击了音乐暂停按钮
            else if (detector.getX() >= 715 && detector.getX() <= 800 && 
                     detector.getY() >= 380 && detector.getY() <= 480)
            {
                if (musicPlayFlag == true)
                {
                    player.pause();// 暂停
                    std::cout << "播放暂停-Paused playback" << std::endl;
                    musicPlayFlag = false;
                }
                else
                {                   
                    player.resume();// 继续播放
                    std::cout << "播放继续Resumed playback" << std::endl;
                    musicPlayFlag = true;
                }
            }
        }   
    }  
}
/****************2048游戏代码结束****************/

/****************井字棋游戏代码开始****************/
void Game::ticTacToe(std::string username, bool userLoginFlag)
{
    // 初始化井字棋游戏
    TicTacToe game;
    game.playGame(username, userLoginFlag);
    return;
}
/****************井字棋游戏代码结束****************/